package com.xiaodu.dynamicdatasource.config;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandler;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.mybatis.spring.boot.autoconfigure.MybatisProperties;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;
import java.beans.FeatureDescriptor;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author: dutianjie
 * @date: 2021/4/22
 * @version: v1.0.0
 * @description: 描述
 **/

@Configuration
@ConditionalOnClass({SqlSessionTemplate.class, SqlSessionFactory.class})
public class MybatisConfig implements BeanPostProcessor {



    @Bean
    public SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dynamicDataSource);
        return sqlSessionFactoryBean.getObject();
    }
//

//    private final MybatisProperties properties;
//    private final Interceptor[] interceptors;
//    private final TypeHandler[] typeHandlers;
//    private final LanguageDriver[] languageDrivers;
//    private final ResourceLoader resourceLoader;
//    private final DatabaseIdProvider databaseIdProvider;
//    private final List<ConfigurationCustomizer> configurationCustomizers;
//
//    public MybatisCofig(MybatisProperties properties, ObjectProvider<Interceptor[]> interceptorsProvider, ObjectProvider<TypeHandler[]> typeHandlersProvider, ObjectProvider<LanguageDriver[]> languageDriversProvider, ResourceLoader resourceLoader, ObjectProvider<DatabaseIdProvider> databaseIdProvider, ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
//        this.properties = properties;
//        this.interceptors = interceptorsProvider.getIfAvailable();
//        this.typeHandlers = typeHandlersProvider.getIfAvailable();
//        this.languageDrivers = languageDriversProvider.getIfAvailable();
//        this.resourceLoader = resourceLoader;
//        this.databaseIdProvider = databaseIdProvider.getIfAvailable();
//        this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
//    }
//
//
//    @Bean
//    public SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource) throws Exception {
//        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
//        factory.setDataSource(dynamicDataSource);
//        factory.setVfs(SpringBootVFS.class);
//        if (StringUtils.hasText(this.properties.getConfigLocation())) {
//            factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
//        }
//
//        this.applyConfiguration(factory);
//        if (this.properties.getConfigurationProperties() != null) {
//            factory.setConfigurationProperties(this.properties.getConfigurationProperties());
//        }
//
//        if (!ObjectUtils.isEmpty(this.interceptors)) {
//            factory.setPlugins(this.interceptors);
//        }
//
//        if (this.databaseIdProvider != null) {
//            factory.setDatabaseIdProvider(this.databaseIdProvider);
//        }
//
//        if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
//            factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
//        }
//
//        if (this.properties.getTypeAliasesSuperType() != null) {
//            factory.setTypeAliasesSuperType(this.properties.getTypeAliasesSuperType());
//        }
//
//        if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
//            factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
//        }
//
//        if (!ObjectUtils.isEmpty(this.typeHandlers)) {
//            factory.setTypeHandlers(this.typeHandlers);
//        }
//
//        if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
//            factory.setMapperLocations(this.properties.resolveMapperLocations());
//        }
//
//        Set<String> factoryPropertyNames = Stream.of((new BeanWrapperImpl(SqlSessionFactoryBean.class)).getPropertyDescriptors()).map(FeatureDescriptor::getName).collect(Collectors.toSet());
//        Class<? extends LanguageDriver> defaultLanguageDriver = this.properties.getDefaultScriptingLanguageDriver();
//        if (factoryPropertyNames.contains("scriptingLanguageDrivers") && !ObjectUtils.isEmpty(this.languageDrivers)) {
//            factory.setScriptingLanguageDrivers(this.languageDrivers);
//            if (defaultLanguageDriver == null && this.languageDrivers.length == 1) {
//                defaultLanguageDriver = this.languageDrivers[0].getClass();
//            }
//        }
//
//        if (factoryPropertyNames.contains("defaultScriptingLanguageDriver")) {
//            factory.setDefaultScriptingLanguageDriver(defaultLanguageDriver);
//        }
//
//        return factory.getObject();
//    }
//
//    private void applyConfiguration(SqlSessionFactoryBean factory) {
//        org.apache.ibatis.session.Configuration configuration = this.properties.getConfiguration();
//        if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
//            configuration = new org.apache.ibatis.session.Configuration();
//        }
//
//        if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
//            Iterator var3 = this.configurationCustomizers.iterator();
//
//            while (var3.hasNext()) {
//                ConfigurationCustomizer customizer = (ConfigurationCustomizer) var3.next();
//                customizer.customize(configuration);
//            }
//        }
//
//        factory.setConfiguration(configuration);
//    }
}
